package von.seiji.cn.test;

import org.junit.Test;
import org.opencv.core.*;
import org.opencv.features2d.DescriptorMatcher;
import org.opencv.highgui.HighGui;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.opencv.objdetect.CascadeClassifier;

import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLDecoder;
import java.nio.charset.Charset;
import java.util.Arrays;

/**
 * 1.  灰度化（减小图片大小）
 * 2. 人脸识别
 * 3. 人脸切割
 * 4. 规一化(人脸直方图)
 * 5. 直方图相似度匹配
 *
 * @author DJZ-PJJ
 * @Description: 比较两张图片人脸的匹配度
 * @date 2019/2/1813:47
 */

public class FaceCompare {

    // 初始化人脸探测器
    static CascadeClassifier faceDetector;

    static {
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
        faceDetector=new CascadeClassifier("E:\\Seiji926\\software\\OpenVC\\opencv430\\sources\\data\\haarcascades\\haarcascade_frontalface_alt.xml");
    }

    static {
        // System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
        URL resource = FaceCompare.class.getClassLoader().getResource("data/opencv_java430.dll");
        URL resource1 = FaceCompare.class.getClassLoader().getResource("data/opencv_videoio_ffmpeg430_64.dll");
        URL resource2 = FaceCompare.class.getClassLoader().getResource("data/opencv_world430.dll");
        try {
            System.load(URLDecoder.decode(resource.getPath(), Charset.defaultCharset().name()));
            System.load(URLDecoder.decode(resource1.getPath(), Charset.defaultCharset().name()));
            System.load(URLDecoder.decode(resource2.getPath(), Charset.defaultCharset().name()));
        } catch (UnsupportedEncodingException e) {
        }
    }


    // 灰度化人脸
    public static Mat conv_Mat(String img) {
        Mat image0 = Imgcodecs.imread(img);

        Mat image1 = new Mat();
        // 灰度化
        Imgproc.cvtColor(image0, image1, Imgproc.COLOR_BGR2GRAY);
        // 探测人脸
        MatOfRect faceDetections = new MatOfRect();
        faceDetector.detectMultiScale(image1, faceDetections);
        Rect[] rects = faceDetections.toArray();

      /*  for (int i = 0; i < rects.length; i++) {
            Imgproc.rectangle(image0,new Point(rects[i].x, rects[i].y), new Point(rects[i].x + rects[i].width, rects[i].y + rects[i].height), new Scalar(0, 0, 255));
            Imgproc.putText(image0,"Face", new Point(rects[i].x, rects[i].y),Imgproc.FONT_HERSHEY_SCRIPT_SIMPLEX, 1.0, new Scalar(0, 255, 0),1,Imgproc.LINE_AA,false);
        }
        // 6 展示图片
        HighGui.imshow("人脸识别", image0);
        HighGui.waitKey(0);*/

        // rect中人脸图片的范围
        for (Rect rect : rects) {
            Mat face = new Mat(image1, rect);
            return face;
        }


        return null;
    }

    public static double compare_image(String img_1, String img_2) {
        Mat mat_1 = conv_Mat(img_1);

      /*  HighGui.imshow("人脸识别", mat_1);
        HighGui.waitKey(0);*/
        Mat mat_2 = conv_Mat(img_2);
       /* HighGui.imshow("人脸识别", mat_2);
        HighGui.waitKey(0);*/
        Mat hist_1 = new Mat();
        Mat hist_2 = new Mat();

        //颜色范围
        MatOfFloat ranges = new MatOfFloat(0f, 256f);
        //直方图大小， 越大匹配越精确 (越慢)
        MatOfInt histSize = new MatOfInt(100000);

      /*  mat_1.convertTo(mat_1, CvType.CV_32F);
        mat_2.convertTo(mat_2, CvType.CV_32F);*/

        Imgproc.calcHist(Arrays.asList(mat_1), new MatOfInt(0), new Mat(), hist_1, histSize, ranges);
        Imgproc.calcHist(Arrays.asList(mat_2), new MatOfInt(0), new Mat(), hist_2, histSize, ranges);

        // CORREL 相关系数
       // double res = Imgproc.compareHist(hist_1, hist_2, Imgproc.CV_COMP_CORREL);
        double res = Imgproc.compareHist(hist_1, hist_2, Imgproc.CV_COMP_CORREL);
        return res;
    }

    public static void main(String[] args) {
        String basePicPath = "C:\\Users\\Administrator\\Desktop\\";
        double compareHist = compare_image(basePicPath + "11.jpg", basePicPath + "22.jpg");
        System.out.println(compareHist);
        if (compareHist > 0.72) {
            System.out.println("人脸匹配");
        } else {
            System.out.println("人脸不匹配");
        }
    }
}
